/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package controladores;

import controladores.exceptions.NonexistentEntityException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import entidades.LoteIngresoRepuesto;
import entidades.IngresoRepuesto;
import entidades.SalidaCombustible;
import entidades.IngresoCombustible;
import entidades.TipoUsuario;
import java.util.ArrayList;
import java.util.List;
import entidades.CambioRepuestosLote;
import entidades.Usuario;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 *
 * @author g
 */
public class UsuarioJpaController implements Serializable {

    public UsuarioJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Usuario usuario) {
        if (usuario.getTipoUsuario() == null) {
            usuario.setTipoUsuario(new ArrayList<TipoUsuario>());
        }
        if (usuario.getLs_cambio_repuesto() == null) {
            usuario.setLs_cambio_repuesto(new ArrayList<CambioRepuestosLote>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            LoteIngresoRepuesto loteIngresoRepuesto = usuario.getLoteIngresoRepuesto();
            if (loteIngresoRepuesto != null) {
                loteIngresoRepuesto = em.getReference(loteIngresoRepuesto.getClass(), loteIngresoRepuesto.getId());
                usuario.setLoteIngresoRepuesto(loteIngresoRepuesto);
            }
            IngresoRepuesto ingresoRepuesto = usuario.getIngresoRepuesto();
            if (ingresoRepuesto != null) {
                ingresoRepuesto = em.getReference(ingresoRepuesto.getClass(), ingresoRepuesto.getId());
                usuario.setIngresoRepuesto(ingresoRepuesto);
            }
            SalidaCombustible salidaCombustible = usuario.getSalidaCombustible();
            if (salidaCombustible != null) {
                salidaCombustible = em.getReference(salidaCombustible.getClass(), salidaCombustible.getId());
                usuario.setSalidaCombustible(salidaCombustible);
            }
            IngresoCombustible ingresoCombustible = usuario.getIngresoCombustible();
            if (ingresoCombustible != null) {
                ingresoCombustible = em.getReference(ingresoCombustible.getClass(), ingresoCombustible.getId());
                usuario.setIngresoCombustible(ingresoCombustible);
            }
            List<TipoUsuario> attachedTipoUsuario = new ArrayList<TipoUsuario>();
            for (TipoUsuario tipoUsuarioTipoUsuarioToAttach : usuario.getTipoUsuario()) {
                tipoUsuarioTipoUsuarioToAttach = em.getReference(tipoUsuarioTipoUsuarioToAttach.getClass(), tipoUsuarioTipoUsuarioToAttach.getId());
                attachedTipoUsuario.add(tipoUsuarioTipoUsuarioToAttach);
            }
            usuario.setTipoUsuario(attachedTipoUsuario);
            List<CambioRepuestosLote> attachedLs_cambio_repuesto = new ArrayList<CambioRepuestosLote>();
            for (CambioRepuestosLote ls_cambio_repuestoCambioRepuestosLoteToAttach : usuario.getLs_cambio_repuesto()) {
                ls_cambio_repuestoCambioRepuestosLoteToAttach = em.getReference(ls_cambio_repuestoCambioRepuestosLoteToAttach.getClass(), ls_cambio_repuestoCambioRepuestosLoteToAttach.getId());
                attachedLs_cambio_repuesto.add(ls_cambio_repuestoCambioRepuestosLoteToAttach);
            }
            usuario.setLs_cambio_repuesto(attachedLs_cambio_repuesto);
            em.persist(usuario);
            if (loteIngresoRepuesto != null) {
                Usuario oldResponsableOfLoteIngresoRepuesto = loteIngresoRepuesto.getResponsable();
                if (oldResponsableOfLoteIngresoRepuesto != null) {
                    oldResponsableOfLoteIngresoRepuesto.setLoteIngresoRepuesto(null);
                    oldResponsableOfLoteIngresoRepuesto = em.merge(oldResponsableOfLoteIngresoRepuesto);
                }
                loteIngresoRepuesto.setResponsable(usuario);
                loteIngresoRepuesto = em.merge(loteIngresoRepuesto);
            }
            if (ingresoRepuesto != null) {
                Usuario oldResponsableOfIngresoRepuesto = ingresoRepuesto.getResponsable();
                if (oldResponsableOfIngresoRepuesto != null) {
                    oldResponsableOfIngresoRepuesto.setIngresoRepuesto(null);
                    oldResponsableOfIngresoRepuesto = em.merge(oldResponsableOfIngresoRepuesto);
                }
                ingresoRepuesto.setResponsable(usuario);
                ingresoRepuesto = em.merge(ingresoRepuesto);
            }
            if (salidaCombustible != null) {
                Usuario oldResponsableOfSalidaCombustible = salidaCombustible.getResponsable();
                if (oldResponsableOfSalidaCombustible != null) {
                    oldResponsableOfSalidaCombustible.setSalidaCombustible(null);
                    oldResponsableOfSalidaCombustible = em.merge(oldResponsableOfSalidaCombustible);
                }
                salidaCombustible.setResponsable(usuario);
                salidaCombustible = em.merge(salidaCombustible);
            }
            if (ingresoCombustible != null) {
                Usuario oldResponsableOfIngresoCombustible = ingresoCombustible.getResponsable();
                if (oldResponsableOfIngresoCombustible != null) {
                    oldResponsableOfIngresoCombustible.setIngresoCombustible(null);
                    oldResponsableOfIngresoCombustible = em.merge(oldResponsableOfIngresoCombustible);
                }
                ingresoCombustible.setResponsable(usuario);
                ingresoCombustible = em.merge(ingresoCombustible);
            }
            for (TipoUsuario tipoUsuarioTipoUsuario : usuario.getTipoUsuario()) {
                tipoUsuarioTipoUsuario.getUsuarios().add(usuario);
                tipoUsuarioTipoUsuario = em.merge(tipoUsuarioTipoUsuario);
            }
            for (CambioRepuestosLote ls_cambio_repuestoCambioRepuestosLote : usuario.getLs_cambio_repuesto()) {
                Usuario oldEncargadoOfLs_cambio_repuestoCambioRepuestosLote = ls_cambio_repuestoCambioRepuestosLote.getEncargado();
                ls_cambio_repuestoCambioRepuestosLote.setEncargado(usuario);
                ls_cambio_repuestoCambioRepuestosLote = em.merge(ls_cambio_repuestoCambioRepuestosLote);
                if (oldEncargadoOfLs_cambio_repuestoCambioRepuestosLote != null) {
                    oldEncargadoOfLs_cambio_repuestoCambioRepuestosLote.getLs_cambio_repuesto().remove(ls_cambio_repuestoCambioRepuestosLote);
                    oldEncargadoOfLs_cambio_repuestoCambioRepuestosLote = em.merge(oldEncargadoOfLs_cambio_repuestoCambioRepuestosLote);
                }
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Usuario usuario) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Usuario persistentUsuario = em.find(Usuario.class, usuario.getId());
            LoteIngresoRepuesto loteIngresoRepuestoOld = persistentUsuario.getLoteIngresoRepuesto();
            LoteIngresoRepuesto loteIngresoRepuestoNew = usuario.getLoteIngresoRepuesto();
            IngresoRepuesto ingresoRepuestoOld = persistentUsuario.getIngresoRepuesto();
            IngresoRepuesto ingresoRepuestoNew = usuario.getIngresoRepuesto();
            SalidaCombustible salidaCombustibleOld = persistentUsuario.getSalidaCombustible();
            SalidaCombustible salidaCombustibleNew = usuario.getSalidaCombustible();
            IngresoCombustible ingresoCombustibleOld = persistentUsuario.getIngresoCombustible();
            IngresoCombustible ingresoCombustibleNew = usuario.getIngresoCombustible();
            List<TipoUsuario> tipoUsuarioOld = persistentUsuario.getTipoUsuario();
            List<TipoUsuario> tipoUsuarioNew = usuario.getTipoUsuario();
            List<CambioRepuestosLote> ls_cambio_repuestoOld = persistentUsuario.getLs_cambio_repuesto();
            List<CambioRepuestosLote> ls_cambio_repuestoNew = usuario.getLs_cambio_repuesto();
            if (loteIngresoRepuestoNew != null) {
                loteIngresoRepuestoNew = em.getReference(loteIngresoRepuestoNew.getClass(), loteIngresoRepuestoNew.getId());
                usuario.setLoteIngresoRepuesto(loteIngresoRepuestoNew);
            }
            if (ingresoRepuestoNew != null) {
                ingresoRepuestoNew = em.getReference(ingresoRepuestoNew.getClass(), ingresoRepuestoNew.getId());
                usuario.setIngresoRepuesto(ingresoRepuestoNew);
            }
            if (salidaCombustibleNew != null) {
                salidaCombustibleNew = em.getReference(salidaCombustibleNew.getClass(), salidaCombustibleNew.getId());
                usuario.setSalidaCombustible(salidaCombustibleNew);
            }
            if (ingresoCombustibleNew != null) {
                ingresoCombustibleNew = em.getReference(ingresoCombustibleNew.getClass(), ingresoCombustibleNew.getId());
                usuario.setIngresoCombustible(ingresoCombustibleNew);
            }
            List<TipoUsuario> attachedTipoUsuarioNew = new ArrayList<TipoUsuario>();
            for (TipoUsuario tipoUsuarioNewTipoUsuarioToAttach : tipoUsuarioNew) {
                tipoUsuarioNewTipoUsuarioToAttach = em.getReference(tipoUsuarioNewTipoUsuarioToAttach.getClass(), tipoUsuarioNewTipoUsuarioToAttach.getId());
                attachedTipoUsuarioNew.add(tipoUsuarioNewTipoUsuarioToAttach);
            }
            tipoUsuarioNew = attachedTipoUsuarioNew;
            usuario.setTipoUsuario(tipoUsuarioNew);
            List<CambioRepuestosLote> attachedLs_cambio_repuestoNew = new ArrayList<CambioRepuestosLote>();
            for (CambioRepuestosLote ls_cambio_repuestoNewCambioRepuestosLoteToAttach : ls_cambio_repuestoNew) {
                ls_cambio_repuestoNewCambioRepuestosLoteToAttach = em.getReference(ls_cambio_repuestoNewCambioRepuestosLoteToAttach.getClass(), ls_cambio_repuestoNewCambioRepuestosLoteToAttach.getId());
                attachedLs_cambio_repuestoNew.add(ls_cambio_repuestoNewCambioRepuestosLoteToAttach);
            }
            ls_cambio_repuestoNew = attachedLs_cambio_repuestoNew;
            usuario.setLs_cambio_repuesto(ls_cambio_repuestoNew);
            usuario = em.merge(usuario);
            if (loteIngresoRepuestoOld != null && !loteIngresoRepuestoOld.equals(loteIngresoRepuestoNew)) {
                loteIngresoRepuestoOld.setResponsable(null);
                loteIngresoRepuestoOld = em.merge(loteIngresoRepuestoOld);
            }
            if (loteIngresoRepuestoNew != null && !loteIngresoRepuestoNew.equals(loteIngresoRepuestoOld)) {
                Usuario oldResponsableOfLoteIngresoRepuesto = loteIngresoRepuestoNew.getResponsable();
                if (oldResponsableOfLoteIngresoRepuesto != null) {
                    oldResponsableOfLoteIngresoRepuesto.setLoteIngresoRepuesto(null);
                    oldResponsableOfLoteIngresoRepuesto = em.merge(oldResponsableOfLoteIngresoRepuesto);
                }
                loteIngresoRepuestoNew.setResponsable(usuario);
                loteIngresoRepuestoNew = em.merge(loteIngresoRepuestoNew);
            }
            if (ingresoRepuestoOld != null && !ingresoRepuestoOld.equals(ingresoRepuestoNew)) {
                ingresoRepuestoOld.setResponsable(null);
                ingresoRepuestoOld = em.merge(ingresoRepuestoOld);
            }
            if (ingresoRepuestoNew != null && !ingresoRepuestoNew.equals(ingresoRepuestoOld)) {
                Usuario oldResponsableOfIngresoRepuesto = ingresoRepuestoNew.getResponsable();
                if (oldResponsableOfIngresoRepuesto != null) {
                    oldResponsableOfIngresoRepuesto.setIngresoRepuesto(null);
                    oldResponsableOfIngresoRepuesto = em.merge(oldResponsableOfIngresoRepuesto);
                }
                ingresoRepuestoNew.setResponsable(usuario);
                ingresoRepuestoNew = em.merge(ingresoRepuestoNew);
            }
            if (salidaCombustibleOld != null && !salidaCombustibleOld.equals(salidaCombustibleNew)) {
                salidaCombustibleOld.setResponsable(null);
                salidaCombustibleOld = em.merge(salidaCombustibleOld);
            }
            if (salidaCombustibleNew != null && !salidaCombustibleNew.equals(salidaCombustibleOld)) {
                Usuario oldResponsableOfSalidaCombustible = salidaCombustibleNew.getResponsable();
                if (oldResponsableOfSalidaCombustible != null) {
                    oldResponsableOfSalidaCombustible.setSalidaCombustible(null);
                    oldResponsableOfSalidaCombustible = em.merge(oldResponsableOfSalidaCombustible);
                }
                salidaCombustibleNew.setResponsable(usuario);
                salidaCombustibleNew = em.merge(salidaCombustibleNew);
            }
            if (ingresoCombustibleOld != null && !ingresoCombustibleOld.equals(ingresoCombustibleNew)) {
                ingresoCombustibleOld.setResponsable(null);
                ingresoCombustibleOld = em.merge(ingresoCombustibleOld);
            }
            if (ingresoCombustibleNew != null && !ingresoCombustibleNew.equals(ingresoCombustibleOld)) {
                Usuario oldResponsableOfIngresoCombustible = ingresoCombustibleNew.getResponsable();
                if (oldResponsableOfIngresoCombustible != null) {
                    oldResponsableOfIngresoCombustible.setIngresoCombustible(null);
                    oldResponsableOfIngresoCombustible = em.merge(oldResponsableOfIngresoCombustible);
                }
                ingresoCombustibleNew.setResponsable(usuario);
                ingresoCombustibleNew = em.merge(ingresoCombustibleNew);
            }
            for (TipoUsuario tipoUsuarioOldTipoUsuario : tipoUsuarioOld) {
                if (!tipoUsuarioNew.contains(tipoUsuarioOldTipoUsuario)) {
                    tipoUsuarioOldTipoUsuario.getUsuarios().remove(usuario);
                    tipoUsuarioOldTipoUsuario = em.merge(tipoUsuarioOldTipoUsuario);
                }
            }
            for (TipoUsuario tipoUsuarioNewTipoUsuario : tipoUsuarioNew) {
                if (!tipoUsuarioOld.contains(tipoUsuarioNewTipoUsuario)) {
                    tipoUsuarioNewTipoUsuario.getUsuarios().add(usuario);
                    tipoUsuarioNewTipoUsuario = em.merge(tipoUsuarioNewTipoUsuario);
                }
            }
            for (CambioRepuestosLote ls_cambio_repuestoOldCambioRepuestosLote : ls_cambio_repuestoOld) {
                if (!ls_cambio_repuestoNew.contains(ls_cambio_repuestoOldCambioRepuestosLote)) {
                    ls_cambio_repuestoOldCambioRepuestosLote.setEncargado(null);
                    ls_cambio_repuestoOldCambioRepuestosLote = em.merge(ls_cambio_repuestoOldCambioRepuestosLote);
                }
            }
            for (CambioRepuestosLote ls_cambio_repuestoNewCambioRepuestosLote : ls_cambio_repuestoNew) {
                if (!ls_cambio_repuestoOld.contains(ls_cambio_repuestoNewCambioRepuestosLote)) {
                    Usuario oldEncargadoOfLs_cambio_repuestoNewCambioRepuestosLote = ls_cambio_repuestoNewCambioRepuestosLote.getEncargado();
                    ls_cambio_repuestoNewCambioRepuestosLote.setEncargado(usuario);
                    ls_cambio_repuestoNewCambioRepuestosLote = em.merge(ls_cambio_repuestoNewCambioRepuestosLote);
                    if (oldEncargadoOfLs_cambio_repuestoNewCambioRepuestosLote != null && !oldEncargadoOfLs_cambio_repuestoNewCambioRepuestosLote.equals(usuario)) {
                        oldEncargadoOfLs_cambio_repuestoNewCambioRepuestosLote.getLs_cambio_repuesto().remove(ls_cambio_repuestoNewCambioRepuestosLote);
                        oldEncargadoOfLs_cambio_repuestoNewCambioRepuestosLote = em.merge(oldEncargadoOfLs_cambio_repuestoNewCambioRepuestosLote);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Long id = usuario.getId();
                if (findUsuario(id) == null) {
                    throw new NonexistentEntityException("The usuario with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Long id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Usuario usuario;
            try {
                usuario = em.getReference(Usuario.class, id);
                usuario.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The usuario with id " + id + " no longer exists.", enfe);
            }
            LoteIngresoRepuesto loteIngresoRepuesto = usuario.getLoteIngresoRepuesto();
            if (loteIngresoRepuesto != null) {
                loteIngresoRepuesto.setResponsable(null);
                loteIngresoRepuesto = em.merge(loteIngresoRepuesto);
            }
            IngresoRepuesto ingresoRepuesto = usuario.getIngresoRepuesto();
            if (ingresoRepuesto != null) {
                ingresoRepuesto.setResponsable(null);
                ingresoRepuesto = em.merge(ingresoRepuesto);
            }
            SalidaCombustible salidaCombustible = usuario.getSalidaCombustible();
            if (salidaCombustible != null) {
                salidaCombustible.setResponsable(null);
                salidaCombustible = em.merge(salidaCombustible);
            }
            IngresoCombustible ingresoCombustible = usuario.getIngresoCombustible();
            if (ingresoCombustible != null) {
                ingresoCombustible.setResponsable(null);
                ingresoCombustible = em.merge(ingresoCombustible);
            }
            List<TipoUsuario> tipoUsuario = usuario.getTipoUsuario();
            for (TipoUsuario tipoUsuarioTipoUsuario : tipoUsuario) {
                tipoUsuarioTipoUsuario.getUsuarios().remove(usuario);
                tipoUsuarioTipoUsuario = em.merge(tipoUsuarioTipoUsuario);
            }
            List<CambioRepuestosLote> ls_cambio_repuesto = usuario.getLs_cambio_repuesto();
            for (CambioRepuestosLote ls_cambio_repuestoCambioRepuestosLote : ls_cambio_repuesto) {
                ls_cambio_repuestoCambioRepuestosLote.setEncargado(null);
                ls_cambio_repuestoCambioRepuestosLote = em.merge(ls_cambio_repuestoCambioRepuestosLote);
            }
            em.remove(usuario);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Usuario> findUsuarioEntities() {
        return findUsuarioEntities(true, -1, -1);
    }

    public List<Usuario> findUsuarioEntities(int maxResults, int firstResult) {
        return findUsuarioEntities(false, maxResults, firstResult);
    }

    private List<Usuario> findUsuarioEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Usuario.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Usuario findUsuario(Long id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Usuario.class, id);
        } finally {
            em.close();
        }
    }

    public int getUsuarioCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Usuario> rt = cq.from(Usuario.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
     public Usuario getUsuario(String name, String pass, String tipo){
        EntityManager em = getEntityManager();                
        Query q = em.createQuery("SELECT u FROM Usuario u INNER JOIN u.tipoUsuario t WHERE u.user_name =:name AND u.user_password =:pass AND t.descripcion =:tipo");        
        
        q.setParameter("name", name);
        q.setParameter("pass", pass);
        q.setParameter("tipo", tipo);
        List<Usuario> resultList = q.getResultList();
        if(!resultList.isEmpty())
            return resultList.get(0);
        return null;
    }
    
}
